<?php
class Item extends LilcartAppModel {

	var $name = 'Item';
	var $actsAs = array(
		'Containable',
		'Translate' => array('title'=>'Title', 'descript'=>'Descript'),
		'Lilcart.LilUpload' => array(
			'fileField'		=> 'image',
			'titleField' 	=> 'dsfd',
			'fileFormat'	=> '{HASH}',
			'dirFormat'		=> '.',
			'baseDir'		=> '{WWW_ROOT}img{DS}items{DS}',
		)
	);
	var $validate = array(
		'title' => array('notEmpty'),
		'price_current' => array('rule'=>'decimal', 'allowEmpty'=>true),
		'price_original' => array('rule'=>'decimal', 'allowEmpty'=>true)
	);
	
	var $hasAndBelongsToMany = array(
		'Category' => array(
			'className'=>'Lilcart.Category',
			'joinTable' => 'categories_items',
			'foreignKey' => 'item_id',
			'associationForeignKey' => 'category_id',
		)
	);
	
	function __construct($id = false, $table = null, $ds = null)	{
		$this->actsAs['Upload']['baseDir'] = Configure::read('LilcartPlugin.imagesPath');
		// create this on fly because table prefix cannot be set in HABTM
		if ($table_prefix = Configure::read('LilcartPlugin.tablePrefix')) {
			$this->hasAndBelongsToMany['Category']['joinTable'] = $table_prefix.'categories_items';
		}
		
		parent::__construct($id = false, $table = null, $ds = null);
	}

/**
 * Callback function
 */
 	function beforeSave() {
		if (empty($this->data['Item']['slug']) && !empty($this->data['Item']['title'])) {
			$this->data['Item']['slug'] = strtolower(Inflector::slug(
				mb_convert_encoding($this->data['Item']['title'], 'ASCII'), '-'));
			if ($this->hasAny(array('Item.slug'=>$this->data['Item']['slug'], 'NOT'=>array('Item.id'=>@$this->data['Item']['id'])))) {
				$i = 2;
				while ($this->hasAny(array('Item.slug'=>$this->data['Item']['slug'].'-'.$i, 'NOT'=>array('Item.id'=>@$this->data['Item']['id'])))) {
					$i++;
					if ($i>100) break;
				}
				$this->data['Item']['slug'] .= '-'.$i;
			}
		}
		return true;
	}

/**
 * Callback function
 */
	function afterSave() {
		if (!empty($this->id)) {
			// update counter cache of categories
			App::import('Model', 'Lilcart.CategoriesItem');
			$CategoriesItem = new CategoriesItem();
			$categories = $CategoriesItem->find('all', array('conditions'=>array('item_id'=>$this->id), 'contain'=>array(), 'fields'=>array('category_id')));
			foreach ($categories as $category) {
				$this->Category->updateAll(array('items_count'=>$this->fetchForCategory($category['CategoriesItem']['category_id'], 'count')), array('Category.id'=>$category['CategoriesItem']['category_id']));
			}
		}
		
		if (!empty($this->data['Item']['image']) && !empty($this->id)) {
			// create thumb and main image
			// load image and get image size
			$img = imagecreatefromjpeg( WWW_ROOT.'img'.DS.'items'.DS.$this->data['Item']['image'] );
			$width = imagesx( $img );
			$height = imagesy( $img );
			
			$new_width = 120;
			$new_height = floor( $height * ( $new_width / $width ) );
			
			// create a new temporary image
			$tmp_img = imagecreatetruecolor( $new_width, $new_height );
			imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );
			imagejpeg( $tmp_img,  WWW_ROOT.'img'.DS.'thumbs'.DS.$this->id.'.jpg');
			
			rename(WWW_ROOT.'img'.DS.'items'.DS.$this->data['Item']['image'], WWW_ROOT.'img'.DS.'items'.DS.$this->id.'.jpg');
		}
	}
	
/**
 * Returns items for specified category.
 *
 * @param int $category_id Node path
 * @param string $kind "all" or "count"
 * @return mixed Items in specified category
 * @access public
 */
	function fetchForCategory($category_id=null, $kind='all') {
		if (is_array($category_id)) {
			if (sizeof($category_id)>1) {
				// find all items that are in every category
				$items = array(); $i = 0;
				$lft_rght = $this->Category->find('all', array('conditions'=>array('Category.id'=>$category_id), 'contain'=>array(), 'fields'=>array('id', 'lft', 'rght')));
				
				foreach ($lft_rght as $category) {
					$categories = array($category['Category']['id']);
					$children = $this->Category->find('list', array('conditions'=>array('Category.rght <'=>$category['Category']['rght'], 'Category.lft >'=>$category['Category']['lft']), 'fields'=>array('slug', 'id'), 'contain'=>array()));
					$categories = array_merge($categories, $children);
					
					App::import('Model', 'Lilcart.CategoriesItem');
					$this->CategoriesItem =& new CategoriesItem();
					$category_items = array_unique($this->CategoriesItem->find('list', array('conditions'=>array('category_id'=>$categories), 'fields'=>array('id', 'item_id'))));
					
					if ($i==0) {
						$items = $category_items;
					} else {
						// keep only items that exist in every category
						$items = array_intersect($items, $category_items);
						// no need for re-run if there are no items left
						if (empty($items)) break;
					}
					$i++;
				}
				// when fetching count - no need for additional query
				if ($kind=='count') return sizeof($items);
				
				if (!empty($items)) {
					return $this->find($kind, array('conditions'=>array('Item.id'=>$items)));
				} else {
					return array();
				}
			} else {
				// get first category
				$category_id = reset($category_id);
			}
		}
		
		// do a simple inner join
		$this->contain(array('CategoriesItem'));
		$this->bindModel(array('hasOne' => array(
			'CategoriesItem' => array(
				'className' => 'Lilcart.CategoriesItem',
				'type' => 'INNER'
			)
		)), false);
		return $this->find($kind, array('conditions'=>array('CategoriesItem.category_id'=>$category_id)));
	}

}
?>